package com.xwq.smartgelleryhub.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xwq.smartgelleryhub.annotation.AuthCheck;
import com.xwq.smartgelleryhub.common.BaseResponse;
import com.xwq.smartgelleryhub.common.ResultUtils;
import com.xwq.smartgelleryhub.constant.UserConstant;
import com.xwq.smartgelleryhub.exception.BusinessException;
import com.xwq.smartgelleryhub.exception.ErrorCode;
import com.xwq.smartgelleryhub.model.dto.excel.*;
import com.xwq.smartgelleryhub.model.entity.Picture;
import com.xwq.smartgelleryhub.model.entity.Space;
import com.xwq.smartgelleryhub.model.entity.User;
import com.xwq.smartgelleryhub.service.PictureService;
import com.xwq.smartgelleryhub.service.SpaceService;
import com.xwq.smartgelleryhub.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Excel导入导出接口
 */
@RestController
@RequestMapping("/excel")
@Slf4j
public class ExcelController {

    @Resource
    private PictureService pictureService;
    
    @Resource
    private SpaceService spaceService;
    
    @Resource
    private UserService userService;

    /**
     * 导出图片数据到Excel
     *
     * @param response HTTP响应
     * @param spaceId 空间ID，可选，为空则导出所有
     */
    @GetMapping("/export/pictures")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public void exportPictures(HttpServletResponse response, @RequestParam(required = false) Long spaceId) {
        try {
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 添加时间戳到文件名，避免缓存问题
            String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String fileName = URLEncoder.encode("pictures_" + timestamp, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            
            // 查询数据
            QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
            if (spaceId != null) {
                queryWrapper.eq("spaceId", spaceId);
            }
            List<Picture> pictureList = pictureService.list(queryWrapper);
            
            // 转换为DTO
            List<ExcelPictureDTO> excelData = new ArrayList<>();
            for (Picture picture : pictureList) {
                ExcelPictureDTO dto = new ExcelPictureDTO();
                BeanUtils.copyProperties(picture, dto);
                excelData.add(dto);
            }
            
            // 写入Excel
            EasyExcel.write(response.getOutputStream(), ExcelPictureDTO.class)
                    .autoCloseStream(false) // 不自动关闭流
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet("pictures")
                    .doWrite(excelData);
                    
            // 确保所有数据都写入
            response.getOutputStream().flush();
            
        } catch (Exception e) {
            log.error("导出Excel异常", e);
            try {
                // 只有在还没开始写Excel时才重置响应
                if (!response.isCommitted()) {
                    response.reset();
                    response.setContentType("application/json");
                    response.setCharacterEncoding("utf-8");
                    response.getWriter().println("{\"code\":500,\"message\":\"导出失败：" + e.getMessage() + "\"}");
                }
            } catch (IOException ex) {
                log.error("设置错误响应失败", ex);
            }
        }
    }

    /**
     * 导入Excel数据到图片表
     *
     * @param file Excel文件
     * @return 导入结果
     */
    @PostMapping("/import/pictures")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<ImportResult> importPictures(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "上传文件不能为空");
            }
            
            // 文件类型校验
            String filename = file.getOriginalFilename();
            if (filename == null || (!filename.endsWith(".xlsx") && !filename.endsWith(".xls"))) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件格式错误，请上传Excel文件");
            }
            
            // 创建监听器
            PictureImportListener listener = new PictureImportListener(pictureService);
            
            // 读取Excel
            EasyExcel.read(file.getInputStream(), ExcelPictureDTO.class, listener)
                    .sheet()
                    .doRead();
            
            // 返回导入结果
            int success = listener.getSuccessCount();
            int fail = listener.getFailCount();
            ImportResult result = new ImportResult(success + fail, success, fail);
            return ResultUtils.success(result);
            
        } catch (IOException e) {
            log.error("导入Excel异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "导入失败：" + e.getMessage());
        }
    }
    
    /**
     * 导出空间数据到Excel
     *
     * @param response HTTP响应
     * @param userId 用户ID，可选，为空则导出所有
     */
    @GetMapping("/export/spaces")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public void exportSpaces(HttpServletResponse response, @RequestParam(required = false) Long userId) {
        try {
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 添加时间戳到文件名，避免缓存问题
            String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String fileName = URLEncoder.encode("spaces_" + timestamp, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            
            // 查询数据
            QueryWrapper<Space> queryWrapper = new QueryWrapper<>();
            if (userId != null) {
                queryWrapper.eq("userId", userId);
            }
            List<Space> spaceList = spaceService.list(queryWrapper);
            
            // 转换为DTO
            List<ExcelSpaceDTO> excelData = new ArrayList<>();
            for (Space space : spaceList) {
                ExcelSpaceDTO dto = new ExcelSpaceDTO();
                BeanUtils.copyProperties(space, dto);
                excelData.add(dto);
            }
            
            // 写入Excel
            EasyExcel.write(response.getOutputStream(), ExcelSpaceDTO.class)
                    .autoCloseStream(false) // 不自动关闭流
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet("spaces")
                    .doWrite(excelData);
                    
            // 确保所有数据都写入
            response.getOutputStream().flush();
            
        } catch (Exception e) {
            log.error("导出Excel异常", e);
            try {
                // 只有在还没开始写Excel时才重置响应
                if (!response.isCommitted()) {
                    response.reset();
                    response.setContentType("application/json");
                    response.setCharacterEncoding("utf-8");
                    response.getWriter().println("{\"code\":500,\"message\":\"导出失败：" + e.getMessage() + "\"}");
                }
            } catch (IOException ex) {
                log.error("设置错误响应失败", ex);
            }
        }
    }

    /**
     * 导入Excel数据到空间表
     *
     * @param file Excel文件
     * @return 导入结果
     */
    @PostMapping("/import/spaces")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<ImportResult> importSpaces(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "上传文件不能为空");
            }
            
            // 文件类型校验
            String filename = file.getOriginalFilename();
            if (filename == null || (!filename.endsWith(".xlsx") && !filename.endsWith(".xls"))) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件格式错误，请上传Excel文件");
            }
            
            // 创建监听器
            SpaceImportListener listener = new SpaceImportListener(spaceService);
            
            // 读取Excel
            EasyExcel.read(file.getInputStream(), ExcelSpaceDTO.class, listener)
                    .sheet()
                    .doRead();
            
            // 返回导入结果
            int success = listener.getSuccessCount();
            int fail = listener.getFailCount();
            ImportResult result = new ImportResult(success + fail, success, fail);
            return ResultUtils.success(result);
            
        } catch (IOException e) {
            log.error("导入Excel异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "导入失败：" + e.getMessage());
        }
    }
    
    /**
     * 导出用户数据到Excel
     *
     * @param response HTTP响应
     * @param userRole 用户角色，可选，为空则导出所有
     */
    @GetMapping("/export/users")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public void exportUsers(HttpServletResponse response, @RequestParam(required = false) String userRole) {
        try {
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 添加时间戳到文件名，避免缓存问题
            String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String fileName = URLEncoder.encode("users_" + timestamp, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            
            // 查询数据
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            if (userRole != null && !userRole.isEmpty()) {
                queryWrapper.eq("userRole", userRole);
            }
            List<User> userList = userService.list(queryWrapper);
            
            // 转换为DTO
            List<ExcelUserDTO> excelData = new ArrayList<>();
            for (User user : userList) {
                ExcelUserDTO dto = new ExcelUserDTO();
                BeanUtils.copyProperties(user, dto);
                // 不导出密码
                dto.setUserPassword(null);
                excelData.add(dto);
            }
            
            // 写入Excel
            EasyExcel.write(response.getOutputStream(), ExcelUserDTO.class)
                    .autoCloseStream(false) // 不自动关闭流
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet("users")
                    .doWrite(excelData);
                    
            // 确保所有数据都写入
            response.getOutputStream().flush();
            
        } catch (Exception e) {
            log.error("导出Excel异常", e);
            try {
                // 只有在还没开始写Excel时才重置响应
                if (!response.isCommitted()) {
                    response.reset();
                    response.setContentType("application/json");
                    response.setCharacterEncoding("utf-8");
                    response.getWriter().println("{\"code\":500,\"message\":\"导出失败：" + e.getMessage() + "\"}");
                }
            } catch (IOException ex) {
                log.error("设置错误响应失败", ex);
            }
        }
    }

    /**
     * 导入Excel数据到用户表
     *
     * @param file Excel文件
     * @return 导入结果
     */
    @PostMapping("/import/users")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<ImportResult> importUsers(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "上传文件不能为空");
            }
            
            // 文件类型校验
            String filename = file.getOriginalFilename();
            if (filename == null || (!filename.endsWith(".xlsx") && !filename.endsWith(".xls"))) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件格式错误，请上传Excel文件");
            }
            
            // 创建监听器
            UserImportListener listener = new UserImportListener(userService);
            
            // 读取Excel
            EasyExcel.read(file.getInputStream(), ExcelUserDTO.class, listener)
                    .sheet()
                    .doRead();
            
            // 返回导入结果
            int success = listener.getSuccessCount();
            int fail = listener.getFailCount();
            ImportResult result = new ImportResult(success + fail, success, fail);
            return ResultUtils.success(result);
            
        } catch (IOException e) {
            log.error("导入Excel异常", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "导入失败：" + e.getMessage());
        }
    }
} 